package com.sdonkey.score.service.impl;

import com.sdonkey.score.bean.UserLoginInfoBean;
import com.sdonkey.score.dto.UserInfoDto;
import com.sdonkey.score.service.IJedisService;
import com.sdonkey.score.service.IUserLoginService;
import com.sdonkey.score.util.MD5;
import com.sdonkey.score.util.StaticVariable;
import com.sdonkey.score.util.SymmetricEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Redis操作类
 *
 * @author ZhaoShihao
 * @version 1.0
 */
@Service
public class JedisServiceImpl implements IJedisService {
    @Autowired
    private JedisPool jedisPool;
    @Autowired
    private IUserLoginService loginService;

    /**
     * 将用户登录信息存入redis
     *
     * @param id           用户ID
     * @param userInfoBean 用户登录信息
     * @param flag         用户是否修改了密码
     * @return 操作是否成功
     */
    @Override
    public String putUserToRedis(String id, UserLoginInfoBean userInfoBean, Integer flag) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(1);
            id = MD5.encode("remember_id:(" + id + ")");
            String key = MD5.encode(id);
            // 将用户信息加密，存入redis
            String username = userInfoBean.getUsername();
            String password = userInfoBean.getPassword();
            if (flag == null || flag != 1) {
                password = SymmetricEncoder.AESEncode(username, password);
            }
            username = SymmetricEncoder.AESEncode(id, username);
            jedis.hset(key, "id", id);
            jedis.hset(key, "username", username);
            jedis.hset(key, "password", password);
            // 设置过期时间为3天
            jedis.expire(key, 60 * 60 * 24 * 3);
            return key;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    /**
     * 从redis中取出用户信息
     *
     * @param request
     * @return 用户的信息（密码为密文保存）
     */
    @Override
    public UserLoginInfoBean getUserByRedis(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            // 获取指定cookie
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("remember")) {
                    Jedis jedis = null;
                    try {
                        jedis = jedisPool.getResource();
                        jedis.select(1);
                        // 从redis中拿出数据并解密
                        String id = jedis.hget(cookie.getValue(), "id");
                        String username = jedis.hget(cookie.getValue(), "username");
                        String pwd = jedis.hget(cookie.getValue(), "password");
                        username = SymmetricEncoder.AESDncode(id, username);
                        // 将取得的数据返回
                        return new UserLoginInfoBean(username, pwd);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        if (jedis != null) {
                            jedis.close();
                        }
                    }
                }
            }
        }
        return null;
    }

    @Override
    public int setUserByToken(Integer userId, String token) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(2);
            if (userId != null) {
                String id = SymmetricEncoder.AESEncode(token, userId.toString());
                jedis.set(token, id);
                // 设置过期时间为30分钟
                jedis.expire(token, 60 * 30);
                return 1;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return 0;
    }

    @Override
    public UserInfoDto getUserByToken(String token) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(2);
            // 从redis中拿出数据并解密
            String id = jedis.get(token);
            id = SymmetricEncoder.AESDncode(token, id);
            if (id != null) {
                UserInfoDto user = loginService.getUser(Integer.parseInt(id));
                if (user != null) {
                    user.setImage(StaticVariable.user_head_url + user.getImage());
                    // 刷新token时间
                    jedis.expire(token, 60 * 30);
                    // 将取得的数据返回
                    return user;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return null;
    }

    @Override
    public Long clearUserByToken(String token) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(2);
            return jedis.del(token);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    @Override
    public int getPayPswError(Integer userId) {
        Jedis jedis = null;
        try {
            String key = MD5.encode("PayPswError:UserID(" + userId + ")");
            jedis = jedisPool.getResource();
            if (jedis.exists(key)) {
                String s = jedis.get(key);
                return Integer.parseInt(s);
            } else {
                jedis.set(key, "5");
                //设置在当天结束时清空密码错误记录
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(new Date());
                calendar.set(Calendar.HOUR, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                jedis.expireAt(key, calendar.getTimeInMillis());
                return 5;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    public Long getUserCount() {
        Jedis jedis = null;
        Long userCount = -1L;
        try {
            jedis = jedisPool.getResource();
            jedis.select(2);
            userCount = jedis.dbSize();
        } catch (Exception e) {
            e.printStackTrace();
            return -1L;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return userCount;
    }

    public Long setPayPswError(Integer userId, boolean isTrue) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String key = MD5.encode("PayPswError:UserID(" + userId + ")");
            if (isTrue) {
                return jedis.decr(key);
            } else {
                return jedis.del(key);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return -1L;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}
